from rest_framework import serializers
from apps.goods.models import SKU, SPU
from apps.contents.models import GoodsCategory
from apps.goods.models import SPUSpecification, SpecificationOption,SKUSpecification
from django.db import transaction


class SKUSpecificationSerializer(serializers.ModelSerializer):
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()
    class Meta:
        model = SKUSpecification
        fields = ['spec_id','option_id']


class SKUSerializer(serializers.ModelSerializer):
    spu_id = serializers.IntegerField()
    category_id = serializers.IntegerField()

    spu = serializers.StringRelatedField(read_only=True)
    category = serializers.StringRelatedField(read_only=True)

    specs = SKUSpecificationSerializer(many=True)

    class Meta:
        model = SKU
        fields = '__all__'

    def create(self, validated_data):
        specs = validated_data.pop('specs')
        with transaction.atomic():
            save_point = transaction.savepoint()
            sku = SKU.objects.create(**validated_data)
            for spec in specs:
                SKUSpecification.objects.create(sku=sku,**spec)
            transaction.savepoint_commit(save_point)
            return sku

    def update(self, instance, validated_data):
        specs = validated_data.pop('specs')
        with transaction.atomic():
            save_point = transaction.savepoint()
            # 调用父类方法更新数据
            super().update(instance,validated_data)
            for spec in specs:
                # 这里实现的简单 spu的id 不允许改变 只能改规格选项的值
                SKUSpecification.objects.filter(sku=instance,spec_id=spec.get('spec_id')).update(option_id=spec.get('option_id'))
            transaction.savepoint_commit(save_point)
            return instance


class ThreeCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = ['id', 'name']


class SPUSerializer(serializers.ModelSerializer):
    class Meta:
        model = SPU
        fields = ['id', 'name']


class SpecificationOptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = SpecificationOption
        fields = ['id', 'value']


class SPUSpecificationSerializer(serializers.ModelSerializer):
    options = SpecificationOptionSerializer(many=True)

    class Meta:
        model = SPUSpecification
        fields = '__all__'
